﻿#ifndef HGL_GRAPH_GEN_SHADER_LIGHT_INCLUDE
#define HGL_GRAPH_GEN_SHADER_LIGHT_INCLUDE

namespace hgl
{
	namespace graph
	{
		namespace shadergen
		{
			const char glsl_light_directional[]=
					"struct DirectionLight\n"
					"{\n"
					"\tvec3 direction;\n"
					"\tvec4 halfVector;\n"
					"\n"
					"\tvec4 ambient;\n"
					"\tvec4 specular;\n"
					"\tvec4 diffuse;\n"
					"};\n"
					"\n"
					"void directionalLight(in int i, in vec3 normal)\n"
					"{\n"
					"\tfloat nDotVP;         // normal . light direction\n"
					"\tfloat nDotHV;         // normal . light half vector\n"
					"\tfloat pf;             // power factor\n\n"
					"\tnDotVP = max(0.0, dot(normal, normalize(vec3 (DirectionLightSource[i].direction))));\n"
					"\tnDotHV = max(0.0, dot(normal, vec3 (DirectionLightSource[i].halfVector)));\n\n"
					"\tif (nDotVP == 0.0)\n"
					"\t{\n"
					"\t    pf = 0.0;\n"
					"\t}\n"
					"\telse\n"
					"\t{\n"
					"\t    pf = pow(nDotHV, FrontMaterial.shininess);\n\n"
					"\t}\n"
					"\tAmbient  += DirectionLightSource[i].ambient;\n"
					"\tDiffuse  += DirectionLightSource[i].diffuse * nDotVP;\n"
					"\tSpecular += DirectionLightSource[i].specular * pf;\n"
					"}\n";

			const char glsl_light_point[]=
					"struct PointLight\n"
					"{\n"
					"\tvec3 position;\n"
					"\tvec4 halfVector;\n"
					"\tvec3 attenuation'\n"
					"\n"
					"\tvec4 ambient;\n"
					"\tvec4 specular;\n"
					"\tvec4 diffuse;\n"
					"};\n"
					"\n"
					"void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
					"{\n"
					"\tfloat nDotVP;       // normal . light direction\n"
					"\tfloat nDotHV;       // normal . light half vector\n"
					"\tfloat pf;           // power factor\n"
					"\tfloat attenuation;  // computed attenuation factor\n"
					"\tfloat d;            // distance from surface to light source\n"
					"\tvec3  VP;           // direction from surface to light position\n"
					"\tvec3  halfVector;   // direction of maximum highlights\n\n"
					"\t// Compute vector from surface to light position\n"
					"\tVP = vec3 (PointLightSource[i].position) - ecPosition3;\n\n"
					"\t// Compute distance between surface and light position\n"
					"\td = length(VP);\n\n"
					"\t// Normalize the vector from surface to light position\n"
					"\tVP = normalize(VP);\n\n"
					"\t// Compute attenuation\n"
					"\tattenuation = 1.0 / (PointLightSource[i].attenuation[0] +\n"
					"\t    PointLightSource[i].attenuation[1] * d +\n"
					"\t    PointLightSource[i].attenuation[2] * d * d);\n\n"
					"\thalfVector = normalize(VP + eye);\n\n"
					"\tnDotVP = max(0.0, dot(normal, VP));\n"
					"\tnDotHV = max(0.0, dot(normal, halfVector));\n\n"
					"\tif (nDotVP == 0.0)\n"
					"\t{\n"
					"\t    pf = 0.0;\n"
					"\t}\n"
					"\telse\n"
					"\t{\n"
					"\t    pf = pow(nDotHV, FrontMaterial.shininess);\n\n"
					"\t}\n"
					"\tAmbient  += PointLightSource[i].ambient * attenuation;\n"
					"\tDiffuse  += PointLightSource[i].diffuse * nDotVP * attenuation;\n"
					"\tSpecular += PointLightSource[i].specular * pf * attenuation;\n"
					"}\n";

			const char glsl_light_spot[]=
					"struct SpotLight\n"
					"{\n"
					"\tvec3 position;\n"
					"\tvec3 direction;\n"
					"\tvec3 attenuation;\n"
					"\tfloat coscutoff;\n"
					"\tfloat exponent;\n"
					"\n"
					"\tvec4 ambient;\n"
					"\tvec4 specular;\n"
					"\tvec4 diffuse;\n"
					"};\n"
					"\n"
					"void spotLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
					"{\n"
					"\tfloat nDotVP;            // normal . light direction\n"
					"\tfloat nDotHV;            // normal . light half vector\n"
					"\tfloat pf;                // power factor\n"
					"\tfloat spotDot;           // cosine of angle between spotlight\n"
					"\tfloat spotAttenuation;   // spotlight attenuation factor\n"
					"\tfloat attenuation;       // computed attenuation factor\n"
					"\tfloat d;                 // distance from surface to light source\n"
					"\tvec3  VP;                // direction from surface to light position\n"
					"\tvec3  halfVector;        // direction of maximum highlights\n\n"
					"\t// Compute vector from surface to light position\n"
					"\tVP = vec3 (SpotLightSource[i].position) - ecPosition3;\n\n"
					"\t// Compute distance between surface and light position\n"
					"\td = length(VP);\n\n"
					"\t// Normalize the vector from surface to light position\n"
					"\tVP = normalize(VP);\n\n"
					"\t// Compute attenuation\n"
					"\tattenuation = 1.0 / (SpotLightSource[i].attenuation[0] +\n"
					"\t    SpotLightSource[i].attenuation[1] * d +\n"
					"\t    SpotLightSource[i].attenuation[2] * d * d);\n\n"
					"\t// See if point on surface is inside cone of illumination\n"
					"\tspotDot = dot(-VP, normalize(SpotLightSource[i].direction));\n\n"
					"\tif (spotDot < SpotLightSource[i].coscutoff)\n"
					"\t{\n"
					"\t    spotAttenuation = 0.0; // light adds no contribution\n"
					"\t}\n"
					"\telse\n"
					"\t{\n"
					"\t    spotAttenuation = pow(spotDot, SpotLightSource[i].exponent);\n\n"
					"\t}\n"
					"\t// Combine the spotlight and distance attenuation.\n"
					"\tattenuation *= spotAttenuation;\n\n"
					"\thalfVector = normalize(VP + eye);\n\n"
					"\tnDotVP = max(0.0, dot(normal, VP));\n"
					"\tnDotHV = max(0.0, dot(normal, halfVector));\n\n"
					"\tif (nDotVP == 0.0)\n"
					"\t{\n"
					"\t    pf = 0.0;\n"
					"\t}\n"
					"\telse\n"
					"\t{\n"
					"\t    pf = pow(nDotHV, FrontMaterial.shininess);\n\n"
					"\t}\n"
					"\tAmbient  += SpotLightSource[i].ambient * attenuation;\n"
					"\tDiffuse  += SpotLightSource[i].diffuse * nDotVP * attenuation;\n"
					"\tSpecular += SpotLightSource[i].specular * pf * attenuation;\n\n"
					"}\n";

			const char glsl_light_infinite_spot[]=
					"struct InfiniteSpotLight\n"
					"{\n"
					"\tvec3 position;\n"
					"\tvec3 direction;\n"
					"\tvec4 halfVector;\n"
					"\tfloat exponent;\n"
					"\n"
					"\tvec4 ambient;\n"
					"\tvec4 specular;\n"
					"\tvec4 diffuse;\n"
					"};\n"
					"\n"
					"void infiniteSpotLight(in int i, in vec3 normal)\n"
					"{\n"
					"\tfloat nDotVP;         // normal . light direction\n"
					"\tfloat nDotHV;         // normal . light half vector\n"
					"\tfloat pf;             // power factor\n"
					"\tfloat spotAttenuation;\n"
					"\tvec3  Ppli;\n"
					"\tvec3  Sdli;\n\n"
					"\tnDotVP = max(0.0, dot(normal, normalize(vec3 (InfiniteSpotLightSource[i].position))));\n"
					"\tnDotHV = max(0.0, dot(normal, vec3 (InfiniteSpotLightSource[i].halfVector)));\n\n"
					"\tPpli = -normalize(vec3(InfiniteSpotLightSource[i].position));\n"
					"\tSdli = normalize(vec3(InfiniteSpotLightSource[i].direction));\n\n"
					"\tspotAttenuation = pow(dot(Ppli, Sdli), InfiniteSpotLightSource[i].exponent);\n"
					"\tif (nDotVP == 0.0)\n"
					"\t{\n"
					"\t    pf = 0.0;\n"
					"\t}\n"
					"\telse\n"
					"\t{\n"
					"\t    pf = pow(nDotHV, FrontMaterial.shininess);\n\n"
					"\t}\n"
					"\tAmbient  += InfiniteSpotLightSource[i].ambient * spotAttenuation;\n"
					"\tDiffuse  += InfiniteSpotLightSource[i].diffuse * nDotVP * spotAttenuation;\n"
					"\tSpecular += InfiniteSpotLightSource[i].specular * pf * spotAttenuation;\n"
					"}\n";
		}//namespace shadergen
	}//namespace graph
}//namespace hgl

#endif//HGL_GRAPH_GEN_SHADER_LIGHT_INCLUDE
